<?php

namespace app\common\model;

use app\common\core\ContentModel;
use app\common\facade\CategoryFacade;
use Overtrue\Pinyin\Pinyin;
use think\Db;
use think\Paginator;

/**
 * Class ArticleModel
 * @package app\common\model
 */
class ArticleModel extends ContentModel
{
    protected $autoWriteTimestamp = true;
    protected $type = ['prop_data' => 'array'];
    protected $auto = ['channel_id', 'name'];

    function __construct($data = [])
    {
        parent::__construct($data);
        $this->cateFacade = CategoryFacade::getFacadeInstance();
        $this->searchFields = 'title|vice_title|description';
    }

    public function setNameAttr($value)
    {
        if (!empty($value)) {
            return $value;
        }
        $pinyin = new Pinyin();
        $value = $pinyin->permalink(trim($this->title), '', PINYIN_KEEP_ENGLISH);

        if (strlen($value) > 45) {
            $value = $pinyin->abbr(trim($this->title), '', PINYIN_KEEP_ENGLISH);
            if (strlen($value) > 45) {
                $value = substr($value, 0, 45);
            }
        }
        $sufix = 0;
        $newValue = $this->fixNumberStart($value);
        while (Db::name('article')->where('name', $newValue)->count() > 0) {
            $sufix++;
            $newValue = $value . '_' . $sufix;
        }
        return $newValue;
    }
    private function fixNumberStart($value)
    {
        $numbers = [];
        if (preg_match('/^\d+/', $value, $numbers)) {
            $first = ['z', 'o', 't', 'th', 'f', 'f', 's', 's', 'e', 'n'][intval($numbers[0][0])];
            return $first . $value;
        }
        return $value;
    }

    public function setChannelIdAttr($value)
    {
        $topCate = CategoryFacade::getTopCategory($this->cate_id);
        return empty($topCate) ? intval($value) : $topCate['id'];
    }

    protected function tagBaseView($model)
    {
        return $model->view(
            $this->cateModel . ' channel',
            ["title" => "channel_title", "name" => "channel_name", "short" => "channel_short", "icon" => "channel_icon", "image" => "channel_image"],
            $this->model . ".channel_id=channel.id",
            "LEFT"
        );
    }

    protected function setCondition($model, $attrs)
    {
        $model = parent::setCondition($model, $attrs);

        if (!empty($attrs['name'])) {
            $sortnames = explode(',', trim($attrs['name']));
            $sortnames = array_map('trim', $sortnames);
            if (count($sortnames) > 1) {
                $this->sortField = 'name';
                $this->sortValues = $sortnames;
            }
            $model->whereIn($this->model . ".name", $sortnames);
        }

        if (!empty($attrs['type'])) {
            $typeint = 0;
            $types = array_filter(array_map('trim', explode(',', $attrs['type'])));
            foreach ($types as $type) {
                $typeint = $typeint | $type;
            }
            $model->where(Db::raw('(' . $this->model . ".`type` & " . $typeint . ') = ' . $typeint));
        }
        if (!empty($attrs['cover'])) {
            $model->where($this->model . '.cover', '<>', '');
        }

        // 默认调用未隐藏的文章，-1不限制
        if (empty($attrs['is_hidden'])) {
            $model->where($this->model . '.is_hidden', '0');
        } elseif ($attrs['is_hidden'] > 0) {
            $model->where($this->model . '.is_hidden', '1');
        }
        return $model;
    }

    /**
     * @param array|Paginator $lists
     * @param array $attrs
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function afterTagList($lists, $attrs)
    {
        if (!empty($lists)) {
            $pids = array_column(is_array($lists) ? $lists : $lists->items(), 'id');
            if (!empty($attrs['withimgs'])) {
                $imgs = Db::name('articleImages')->whereIn('article_id', $pids)->select();
                $imgs = array_index($imgs, 'article_id', true);
                $lists = $this->appendTagData($lists, 'imgs', $imgs);
            }
            if (!empty($attrs['withattaches'])) {
                $attaches = Db::name('articleAttachments')->whereIn('article_id', $pids)->select();
                $attaches = array_index($attaches, 'article_id', true);
                $lists = $this->appendTagData($lists, 'attaches', $attaches);
            }
            if ($lists instanceof Paginator) {
                $lists->each(function ($item) {
                    return ArticleFieldsModel::readTransData($item);
                });
            } else {
                foreach ($lists as $k => $item) {
                    $lists[$k] = ArticleFieldsModel::readTransData($item);
                }
            }
        }
        return $lists;
    }

    protected function afterTagItem($item, $attrs = [])
    {
        if (!empty($item)) {
            $item['digg'] = $item['digg'] + intval($item['v_digg']);
            $item['views'] = $item['views'] + intval($item['v_views']);
            $item = ArticleFieldsModel::readTransData($item);
        }
        return $item;
    }
}
